/*
 * @Author: hongbin
 * @Date: 2021-11-16 20:09:08
 * @LastEditors: hongbin
 * @LastEditTime: 2021-11-20 18:28:09
 * @Description:更新document组件
 */
import { Delete, Edit, SettingsBackupRestore } from "@mui/icons-material";
import { Button, Divider, IconButton, Input } from "@mui/material";
import { FC, Fragment, ReactElement, useState } from "react";
import styled from "styled-components";
import { transformBSON } from "../../api/types";
import { NoticeRef } from "../Notice";
import AddField from "./AddField";
import MongodbTypePick from "./MongodbTypePick";

interface IProps {
  data: { [key: string]: any };
  onSubmit: (c: any, d: any) => void;
  onCancel: () => void;
}

const UpdateField: FC<IProps> = ({
  data: { _id, ...data },
  onSubmit,
  onCancel,
}): ReactElement => {
  const [fields, setFields] = useState(data);
  const [fieldType, setFieldType] = useState<{ [key: string]: any }>({}); //选择更改字段的类型
  const [removeField, setRemoveField] = useState<string[]>([]); //删除的字段
  const [addField, setAddField] = useState(false);

  const handleSubmit = () => {
    //发生更新的字段和新值
    const changed: { [key: string]: any } = {};
    // 避免更新和删除属性冲突
    const entries = Object.entries(fieldType).filter(
      ([field]) => !removeField.includes(field)
    );
    entries.forEach(([field, type]) => {
      changed[field] = transformBSON[type](fields[field]);
    });
    if (!entries.length && !removeField.length) {
      NoticeRef.current?.open({ message: "没有变更", type: "info" });
    } else onSubmit(changed, removeField);
  };

  const setType = (key: string) => (type: string) =>
    setFieldType(prev => ({ ...prev, [key]: type }));

  return (
    <Container>
      {Object.entries(fields).map(([key, value]) => {
        const needChange = !!fieldType[key];
        return (
          <div key={key}>
            <strong>{key}</strong>
            <Input
              disabled={!needChange}
              value={value}
              onChange={e => {
                setFields(prev => ({ ...prev, [key]: e.target.value }));
              }}
            />
            {needChange ? (
              <>
                <MongodbTypePick onChange={setType(key)} />
                <IconButton
                  onClick={() => {
                    setFieldType(prev => {
                      const field = { ...prev };
                      delete field[key];
                      return field;
                    });
                    setFields(prev => ({ ...prev, [key]: data[key] }));
                  }}
                >
                  <SettingsBackupRestore />
                </IconButton>
                <IconButton
                  onClick={() => {
                    setFields(prev => {
                      const field = { ...prev };
                      delete field[key];
                      return field;
                    });
                    setRemoveField(prev => [...prev, key]);
                  }}
                >
                  <Delete />
                </IconButton>
              </>
            ) : (
              <IconButton onClick={() => setType(key)("string")}>
                <Edit />
              </IconButton>
            )}
          </div>
        );
      })}
      {addField ? (
        <AddField
          onAdd={({ key, value, type }) => {
            setFields(prev => ({ ...prev, [key]: value }));
            setType(key)(type);
            setAddField(false);
          }}
          handleClose={() => setAddField(false)}
        />
      ) : (
        <Button
          size="small"
          variant="outlined"
          onClick={() => setAddField(true)}
        >
          增加字段
        </Button>
      )}
      {removeField.length ? (
        <Fragment>
          <Divider />
          <span>删除的字段</span>
          {removeField.map(field => (
            <div key={field}>
              {field}
              <Button
                variant="text"
                onClick={() => {
                  setRemoveField(prev => prev.filter(item => item !== field));
                  setFields(prev => {
                    const payload = { ...prev };
                    payload[field] = data[field];
                    return payload;
                  });
                }}
              >
                恢复
              </Button>
            </div>
          ))}
        </Fragment>
      ) : null}
      <br />
      <Button variant="contained" onClick={handleSubmit}>
        更新
      </Button>
      <Button onClick={onCancel}>取消</Button>
    </Container>
  );
};

export default UpdateField;

const Container = styled.div`
  & > div {
    display: flex;
    align-items: center;
    min-height: 2rem;
    strong {
      min-width: 5rem;
      display: inline-block;
    }
    select {
      margin: 0 1rem;
    }
  }
  button {
    margin: 0.5rem;
    margin-left: 0;
  }
`;
